<script>
  // JS API 调用指南

        /*
            一、概述

                    JS API 是宿主环境为开发者提供的 JavaScript接口，
                    
                    用于 实现与宿主应用的交互，支持调用设备能力(如摄像头、地理位置)、访问用户数据（如昵称、头像） 以及触发宿主功能（如分享、支付）等。


                    JS API 由小程序开发框架提供，可便捷地调用宿主的原生能力，扩展小程序的功能范围，助理开发者打造更丰富的应用程序。
        */



        /*
            二、优势

                      优势                                描述

                    ①、扩展功能                    借助 JS API ，开发者可调用抖音原生能力，如拍摄、录音、获取设备信息、扫码等，扩展小程序功能边界，满足多样业务功能。

                    ②、提升用户体验                利用JS API实现流畅页面切换、高效数据交互和个性化界面展示，如预加载页面、展示个性化推荐。

                    ③、增强社交互动                小程序JS API 支持社交功能集成，可实现内容分享。
        */



        /*
            三、应用场景

                       场景                                 描述
                    ①、内容创作与分享              用户可调用API拍摄、编辑素材并分享到抖音，吸引挂关注和互动。

                    ②、电商购物                   用JS API 实现商品展示、搜索、下单支付等，获取用户位置金准配送，分享商品促进销售。

                    ③、生活服务                   通过JS API 获取用户位置推荐商家、展示导航、完成支付、推送订单通知。

                    ④、娱乐游戏                   用 JS API 实现流畅运行、身份验证、数据存储同步等，播放音效、打造画面、实现玩家互动。
        */


        /*
            四、类型

                        类型                       特点                                          代码示例
                      
                      ①、同步API          调用时立即执行并返回结果，执行过程中阻塞程序              const systemInfo = tt.getSystemInfoSync();
                                                                                                console.log('系统信息:', systemInfo);

                                                                                                在这个示例中， tt.getSystemInfoSync()  是一个同步API，调用后会立即返回系统信息，程序会等待
                                                                                                该API执行完成，将结果存储在 systemInfo 变量中，然后继续执行后续的 console.log 语句。


                      ②、异步API          调用时布里吉返回结果，后台执行，通过回调、Promise         tt.request({
                                          等返回结果。                                               url: 'https://example.com/api/data',
                                                                                                    method: 'GET',
                                                                                                    success: function (res) {
                                                                                                        console.log('请求成功:', res.data);
                                                                                                    },
                                                                                                    fail: function (err) {
                                                                                                        console.log('请求失败:', err);
                                                                                                    },
                                                                                                    complete: function () {
                                                                                                        console.log('请求完成');
                                                                                                    }
                                                                                                });

                                                                                                在这个示例中，tt.request 是一个异步API，调用后程序会继续执行后续代码，不会等待请求完成。

                                                                                                    ①、当请求成功时，会调用 success 回调函数，将服务器返回的数据作为参数传入。

                                                                                                    ②、若请求失败，会调用 fail 回调函数，将错误信息作为参数传入；无论请求成功还是失败，最后都会
                                                                                                       调用 complete 回调函数。
        */


        /*
            五、调用

                    1、调用流程

                              ①、确定需求：  明确你想要实现的功能，例如是进行网络请求获取数据，还是调起设备的摄像头拍照等，从而确定需要使用的具体 JS API

                              ②、阅读文档：  在抖音开放平台的官方文档中查找对应API的详细信息，包括 API的名称、功能描述、参数列表、返回值、调用示例以及可能的错误码等。

                              ③、参数准备：  根据API文档的要求，准备好调用API所需的参数。参数的类型、格式和数量必须严格按照文档规定，否则可能导致调用失败。

                              ④、错误处理：  在调用API时，要考虑到可能出现的错误情况，为API的 fail 回调函数编写相应的错误处理逻辑，以便在调用失败时能给用户合适的提示。

                              ⑤、结果处理：  对于API调用成功返回的结果，在 success 回调函数中进行处理，如将数据展示在页面上、进行进一步的计算等。

                              ⑥、完成回调：   无论API调用成功还是失败，  complete 回调函数都会执行，可在其中进行一些通用的收尾操作，如隐藏加载提示等。


                    2、注意事项：

                                  <1>、域名白名单设置：  
                                        
                                          每个小程序使用网络API前需设置域名白名单，且只能与白名单指定域名通信。

                                              ①、域名需满足支持HTTP上协议、非IP地址（局域网IP除外）或 localhost、可配置端口且严格匹配、必须ICP备案等条件。

                                              ②、配置流程： 登录抖音开放凭条---控制台，进入对应小程序详情，选择 【开发】---【开发配置】，点击【域名管理】设置。

                                          详情请参见  "配置域名白名单" https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/network/network#%E9%85%8D%E7%BD%AE%E5%9F%9F%E5%90%8D%E7%99%BD%E5%90%8D%E5%8D%95


                                  <2>、超时时间：

                                          网络请求默认超时时间和最大超时时间都是60s，可在 app.json 中通过 networkTimeout 配置修改：

                                              例如：

                                                    // 在JavaScript对象字面量中设置网络超时时间
                                                    const networkTimeout = {
                                                        request: 10000, // 设置request请求超时时间为10秒
                                                        downloadFile: 20000 // 设置downloadFile下载文件超时时间为20秒
                                                    };
                                                    console.log(networkTimeout);


                                  <3>、请求头限制：

                                              网络请求的请求头中的 referer 字段和  user-agent 不可设置。

                                              详情参见： “在网络资源请求添加 referer” 规则： https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/tutorial/basic-ability/referrer-policy

                                  <4>、小程序后台状态：

                                              小程序进入后台5s后，网络请求接口调用都会无法调用，并回调错误 app in background.



                    3、调用示例

                                以 tt.request 为例，以下是一个完整的代码示例：

                                        
                                      // 封装网络请求函数
                                      function sendRequest(url, method, data) {
                                          return new Promise((resolve, reject) => {
                                              tt.request({
                                                  url: url,
                                                  method: method,
                                                  data: data,
                                                  header: {
                                                      'Content-Type': 'application/json'
                                                  },
                                                  success: function (res) {
                                                      console.log('请求成功', res.data);
                                                      resolve(res.data);
                                                  },
                                                  fail: function (err) {
                                                      console.log('请求失败', err);
                                                      reject(err);
                                                  },
                                                  complete: function () {
                                                      console.log('请求完成');
                                                  }
                                              });
                                          });
                                      }


                                      // 调用封装的网络请求函数
                                      async function fetchData() {
                                          try {
                                              const apiUrl = 'https://your-server.com/api/your-path';  
                                              const requestMethod = 'POST';
                                              const requestData = {
                                                  key1: 'value1',
                                                  key2: 'value2'
                                              };
                                              const result = await sendRequest(apiUrl, requestMethod, requestData);
                                              // 处理返回的数据
                                              console.log('处理返回的数据:', result);
                                          } catch (error) {
                                              // 处理错误
                                              console.log('请求出错:', error);
                                          }
                                      }

                                      // 调用fetchData函数发起请求
                                      fetchData();



                                ★、代码说明：

                                          <1>、封装网络请求函数：sendRequest函数封装了tt.request的调用逻辑，使用Promise来处理异步操作，使得代码更易于管理和复用。
                                            
                                                函数接受三个参数：url（请求的服务器地址）、method（请求方法）和data（请求数据）。


                                          <2>、tt.request调用：在sendRequest函数内部，使用tt.request发起网络请求。设置了请求的url、method、data和请求头header。
                                                
                                                success回调函数在请求成功时将返回的数据通过resolve方法传递出去，fail回调函数在请求失败时将错误信息通过reject方法传递出去。


                                          <3>、调用封装函数：fetchData函数是一个异步函数，使用await关键字调用sendRequest函数，等待请求结果返回。
                                                
                                                如果请求成功，将返回的数据存储在result变量中，并进行进一步的处理；如果请求失败，通过catch块捕获错误并进行处理。


                                          <4>、发起请求：  最后调用 fetchData 函数，发起网络请求。
        */  

        /*
            六、权限

                      在小程序中调用JS  API 是否需要提前申请权限，取决于具体API的能力类型。  详情参见：  能力概述 https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/introduction/capabilities


                      1、权限分类与申请规则

                                    能力类型                                 适用场景                            申请/授权流程

                                ①、基础能力 & 进阶能力(无需申请)              不涉及用户隐私或敏感信息的API         开发者可直接调用，无需额外申请或用户授权。

                                ②、高级能力（需平台审核）                     涉及用户隐私、数据安全或平台核心       ①、登录抖音开放平台，进入小程序控制台，在【能力管理】中选择所需权限（如 【用户数据能力】中的【抖音账号数据】）
                                                                            资源的API 
                                                                                                                ②、资质审核：  部分权限需提交企业资质或业务说明(如支付权限需提供 《支付业务许可证》)

                                                                                                                ②、配置白名单：   例如网络请求API需在【开发配置】中添加域名白名单。

                                ③、敏感能力（需用户授权）                     直接影响用户隐私或设备共功能的API      1、声明权限:  在app.json中声明 permission 字段。
                                                                                                                      {
                                                                                                                        "permission": {
                                                                                                                          "scope.userLocation": {
                                                                                                                            "desc": "您的位置信息将用于附近商家推荐"
                                                                                                                          }
                                                                                                                        }
                                                                                                                      }

                                                                                                                2、动态申请：调用API前使用 tt.authorize 或 tt.request 触发授权弹窗
                                                                                                                      tt.authorize({
                                                                                                                        scope: 'scope.userLocation',
                                                                                                                        success() {
                                                                                                                          tt.getLocation({ success: (res) => console.log(res) });
                                                                                                                        },
                                                                                                                        fail() {
                                                                                                                          tt.showModal({ title: '提示', content: '请授权位置权限' });
                                                                                                                        }
                                                                                                                      });


                        2、权限申请原则

                                  ①、按需申请：   仅申请与狠心功能相关的权限，避免过度手机用户信息。

                                  ②、分阶段授权： 例如现请求基础权限（如地理位置），在使用高级功能时在请求敏感权限（如相册）s

                                  ③、用户引导：   在授权弹窗中清晰说明权限用途（如"获取位置信息以推荐附近餐厅"）



                        3、错误处理与兼容性

                                  ①、权限拒绝处理：  在 fial 回调中引导用户到设置页手动授权。

                                            tt.openSetting({
                                              success(res){
                                                if(res.authSetting['scope.userLocation']){
                                                  // 用户已授权，重新调用API
                                                }
                                              }
                                            })


                                  ②、版本兼容： 使用 tt.canUse 判断API支持情况。

                                            if(tt.canUse('tt.getLocation')){
                                                // 执行 API 调用
                                            }else{
                                                console.log('当前版本不支持该API')
                                            }

                        4、隐私协议配置

                                  ①、必要性：  根据《个人信息保护法》，处理用户个人信息需在隐私协议中明确说明。

                                  ②、配置方法： 在控制台 【设置】----【用户隐私保护协议】 中填写协议内容，并通过 tt.showPrivacySetting 引导用户阅读。

                                              详情请参见  小程序隐私协议开发指南 https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/tutorial/security-requirements/privacy-authorize

                        5、注意事项

                                  1、权限政策变化：  平台可能调整权限要求 （如 2025年部分权限回收，需定期查看抖音开放平台公告）。

                                  2、审核风险：  未正确申请权限或滥用权限可能导致小程序审核不通过或被封禁。

                                  3、用户体验：  避免频繁弹出授权弹窗，确保权限申请与用户操作场景一致。

                              通过以上步骤，开发者可合规、高效地管理小程序的JS API权限，既满足功能需求，有保障用户隐私安全。
        */   
       
        /*
            七、常见问题

                        1、兼容性问题：  
                                              
                                  不同版本的抖音宿主环境对小程序 JS API 的支持可能存在差异。开发者需要关注抖音开放平台的文档，了解各API的最低支持版本，并在开发过程中进行兼容性处理。

                                  可以使用 tt.canUse 方法来判断某个API、回调、参数、组件等是否在当前版本可用。

                                  例如：

                                            if(tt.canUse('tt.getLocation')){
                                                tt.getLocation({
                                                   type:'wgs84',
                                                   successs(res){
                                                      console.log("获取位置成功"，res)；
                                                   },
                                                   fail(res){
                                                      console.log("获取位置失败"，res)；
                                                   }
                                                })
                                            }else{
                                                console.log("当前版本不支持获取位置ＡＰＩ");
                                            }


                       2、性能问题：

                                  频繁调用某些API （如网络请求、数据存储等） 可能会影响小程序的性能。开发者应合理优化API调用罗姐，避免不必要的重复调用。

                                  例如对网络请求，可设置缓存机制，当数据为过期时直接从缓存读取，减少网络请求次数；

                                  对于数据存储操作，批量处理数据，减少频繁读写对性能的影响。

                                  同时，在使用异步API时，要注意处理好回调地狱问题，可通过Promise、async/await 等方式优化代买结构，提高代码可读性和可维护性。


                      3、如何避免API调用频率限制？

                                  高频API （如 getUserInfo） 需增加调用时间间隔保护逻辑：

                                            let  lastCallTime= 0;

                                            function safeGetUserInfo(){
                                                if(Date.now()-lastCallTime <2000) return;
                                                lastCallTime = Date.now();
                                                tt.getUserInfo();
                                            }
        */
        
</script>